package com.itheima.service.impl;

import cn.itheima.health.service.OrderInfoService;
import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.OrderSettingMapper;
import com.itheima.pojo.Member;
import com.itheima.pojo.Order;
import com.itheima.utils.DateUtils;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;
@Service  // 添加@Service 注解  表示 这是一个 service层
@Transactional //后期如果 有事务 我们就添加事务注解
public class OrderInfoServiceImpl implements OrderInfoService {

    @Autowired
    private MemberMapper memberMapper;  //因为是根据已有的 手机号码 查询客户信息  所以这是操作会员的 Mapper

    @Autowired   //这里因为 涉及到另外一张表的Sql 语句查询 所以 需要 新建一个Mapper 映射对象
    private OrderSettingMapper orderSettingMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Override
    public Order addOrder(Map<String, Object> map) {
        //创建一个Order 实体类对象  后面需要用到里面的参数
        Order order = new Order();
        String setmealId = (String) map.get("setmealId"); //获取预约套餐 的Id
        //  因为后面要将 order 返回 所以这里将 基本信息封装

        order.setSetmealId( Integer.parseInt(setmealId));
        order.setOrderStatus("0");
        //  表示从前端页面中 封装的Map里 获取orderType的值
        String orderType = (String) map.get("orderType");
        order.setOrderType(orderType);

        /*   ===============    查询Sql语句 得到 member的值 判断用户 是新用户 还是老用户    ========================*/
        //判断用户 是否是新用户 / 会员 ？  可以通过访问后台的数据 查询手机号码 是否存在 判断是否新用户
                //这里可以通过map 拿到客户手机号
        //通过Map 的key 获取值  map.get（" "）
        String telephone = (String) map.get("telephone");
        // 创建一个 根据 电话查询数据库Mapper 对应的Sql语句  再数据库中 要么找得到 要么找不到
            //  为什么返回的是一个Menber 对象？  因为Member 对象实体类中 就有telephone 属性
         Member member = memberMapper.findMemberByTelephone(telephone);
         //然后 根据 member 返还的值 进行判断

/*   =============     根据客户选择的当天日期 查询后台数据库  得到后端最大预约数 和已有的预约数  然后进行判断  ============*/
        // 根据日期 查询预约表 是否当天以及预约满  满： throws 自定义异常 信息；   不满：  可以预约，然后更新预约表+1，生成订单
        String dateparam = (String) map.get("orderDate");  //用户预约的日期
        order.setOrderDate(DateUtils.parseString2Date(dateparam));
        //这里  再map 中得到 这用户预约的日期  是为了 到数据库中找 数据库中  最大预约人数 和已经预约的人数
                //然后进行比较 判断 当天是否还可以再进行预约
              Long cont =   orderSettingMapper.findIsAvalibleByDate(dateparam);

        // 是否可以预约 判断 分为：
                //当可以预约：
            if (cont > 0 ){
                           // 用户再当天有没有预约过当前同一个套餐
                            // 用户 当天 没有预约过同一个套餐

                //如果是兄用户 就不用进行 上面的预约判断  可以直接预约
                //如果member ==null
                if (member==null){
                    //因为对象是空  所以这里 先创建一个对象  避免空指针异常
                    member =new Member();
                    //说明客户第一次预约  就把用户的信息 插入到数据库表中   注意： 这里插入的信息 与数据库对应的字段有关
                    //数据库中需要那些字段，这里就 通过 member 实体类的 set 方法 插入那些数据
                    member.setRegTime(new Date());
                    member.setSex((String) map.get("sex"));
                    member.setName((String) map.get("name"));
                    member.setPhoneNumber(telephone);
                    member.setIdCard((String) map.get("idCard"));
                    // 所以这里就用到 会员表 memberMapper 并且添加一个 add 插入的sql 方法
                    System.out.println("+++++++++++++++++++++++++++++++++++++++"+(String) map.get("name"));
                    memberMapper.addMember(member);  //主键自增长 返回主键

                    // 将member.getId放到新会员中 就封装了 新会员的Id
                    order.setMemberId(member.getId());

                    //这里因为member 为空 所以表示该客户 是新用户  可以直接预约  不用进行下面的 预约判断
                    orderMapper.addOrder(order); //order  添加订单 并且 存放的是用户的一些基本信息
                     orderSettingMapper.updateResersionsByDate(dateparam);    //   相应的Sql语句 做的就是insert into 操作 并且订单预约人数+1

                }
                //这里是老用户的预约订单
                else {
                    //所以需要进行 查询 预约套餐表 t_order 用户是否在当天有没有预约过当前同一个套餐 进行一个判断

                    //   我们在给Sql 语句添加方法 时 括号中 传入的 参与  对应的就是数据库中  表的 字段
                            //然后 我们在sql 语句中 传入这些参数 进行Sql 语句的增删改查
                  long num =  orderMapper.findOrderByMemeberId(member.getId(),dateparam,Integer.parseInt(setmealId) );
                    System.out.println( num );  //这里 返还的 主键自增长 是一个超大的整形，  所以会导致异常数据  主键 就不会自增长  主键就会显示空
                    //  num  = -25413654758   所以这里主键没有自增长  主键没有值
                         //  需要在 applicationContext-mybatis.xml 配置文件 中 将  配置一个可以批量执行的sql
                         // 中的<constructor-arg name="executorType" value="BATCH"></constructor-arg>  中的   value="BATCH"  value 值 改为 ：simple  或者注销
                    if (num>0){
                        // 如果查询语句有值  说明这是一个老用户 说明有过预约了 就不能在预约 直接抛出异常
                        throw new RuntimeException("已经预约过 请下次再预约");
                    }else {
                        // 将member.getId放到老会员中 就封装了 老会员的Id
                        order.setMemberId(member.getId());
                        // 如果没有返回值 就说明 可以预约  接下来 就是 添加订单和客户的信息 然后预约人数+1 的操作
                                // 因为是重复性的代码 所以 我们可以将 以下代码 我们可以进行一个封装
                        //封装代码：
                        orderIsOk(order,dateparam);

                      /*  orderMapper.addOrder(order); //order  添加订单 并且 存放的是用户的一些基本信息
                        orderSettingMapper.updateResersionsByDate(dateparam);    //   相应的Sql语句 做的就是insert into 操作 并且订单预约人数+1 */
                    }
                }
                //这里代表的是 member 不为空 表示用户存在

            }else {
                //不可以预约
                throw  new RuntimeException(" 预约已满");
            }
            //最后订单 添加成功 然后返回订单
        return order ;
    }
    private void orderIsOk(Order order, String dateparam) {
        orderMapper.addOrder(order);
        orderSettingMapper.updateResersionsByDate(dateparam);
    }


    public Map findOrderDetail(int orderid) {
        return orderMapper.findOrderDetail(orderid);
    }

}
